Lesson
Purpose
For security reasons, it is forbidden to store clear passwords directly in the page code or in a database.
Why we chose to hash the password
There are two solutions to secure passwords:
- Encryption: functions modifying the password (e.g. replacing
characters with other characters according to a set of predefined rules).
- Hashing: Generating a signature for a string of characters.
Signature = description of the characteristics of the password
(example: length, type, etc. but in a more complex version).
The result is a string of characters, a kind of code, which
allows you to check if an entered password matches the signature.
It is not possible to find the password in reverse.
Hash functions
There are 2 functions in PHP to hash passwords:
- password_hash(): to generate a signature based on a password
(PHP Doc)
- password_verify(): to verify if the password matches a given signature
(PHP Doc)
Both functions are detailed below.
1. password_hash()
- $var1: password
- $var2: algorithm to use. We use the constants listed on this page:
PHP Doc. Very often the default value (PASSWORD_DEFAULT) is used.
- $var3: salt (quite never used) and cost. The cost allows to increase the time to generate the signature
(this will make it more time/difficult for a hacker to decrypt the password).
By default, the cost is 10. The higher this number is, the longer it will
take the processor to generate a signature. In 2020 we tend to put a cost of 13.
Code
echo password_hash('Doe', PASSWORD_DEFAULT, ['cost' => 13]);
Output: the password_hash() function returns a string which is the
signature of the password:
Result
$2y$13$EA0EdRogXIqAPx9HTkcCo.u7Cbbp5xfgf1jLM8i3WlV3E59/9wAwe
- In the above signature generated, the cost is $13 (4th position).
- Now that we have generated the password signature, we want to check if the password entered by the user matches the signature.
2. password_verify()
- $var1: password entered by the user.
- var2: signature (previously generated with password_hash)
Code
// Instead of doing the verification this way (unsecured)...
if ($_POST['password'] === 'Doe') {
/* do something */
}
// ...we use this (secure version with hash):
$signature = '$2y$13$EA0EdRogXIqAPx9HTkcCo.u7Cbbp5xfgf1jLM8i3WlV3E59/9wAwe';
if (password_verify($_POST['password'], $signature])) {
/* do something */
}